package com.chenwc.netty.tcp.listener;

import com.alibaba.fastjson.JSONObject;
import com.chenwc.netty.tcp.config.ChannelMap;
import com.chenwc.netty.tcp.coder.Message;
import com.chenwc.netty.tcp.enums.MessageEnum;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import java.util.Objects;

/**
 * 数据处理器，针对不同类型数据分类处理 在处理不同接收数据时使用了枚举类型，
 * 在使用switch时可以做下处理，具体参考代码，这里只演示如何操作，并没实现数据处理业务类。
 * @author chenwc
 * @date 2023/5/28 1:01
 */
public class ServerListenerHandler extends SimpleChannelInboundHandler<Message> {

    private static final Logger log = LoggerFactory.getLogger(ServerListenerHandler.class);

    /**
     * 定义本类的静态对象
     */
    private static ServerListenerHandler serverListenerHandler;


    /**
     * 添加 @PostConstruct 注解的方法
     */
    @PostConstruct
    public void init() {
        serverListenerHandler = this;
    }

    /**
     * 设备接入连接时处理
     *
     * @param ctx
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        log.info("有新的连接：【{}】", ctx.channel().id().asLongText());
        String key = ctx.channel().id().asLongText();
        // 保存当前连接
        ChannelMap.addChannel(key, ctx.channel());
    }

    /**
     * 数据处理
     *
     * @param ctx
     * @param msg
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Message msg) {

        //log.info("receive msg: " + msg.toJsonString());
        // 获取消息实例中的消息体
        String body = msg.getBody();
        // 对不同消息类型进行处理
        MessageEnum type = MessageEnum.getStructureEnum(msg);

        JSONObject contentJson = JSONObject.parseObject(body);
        String ep_id = contentJson.containsKey("ep_id")?contentJson.getString("ep_id"): "";
        if (StringUtils.isNotEmpty(ep_id)){
            switch (Objects.requireNonNull(type)) {
                case CONNECT:
                    // TODO 心跳消息处理
                    //log.info(type.content + "消息内容: " + content);
                    log.info("收到来自设备 ep_id: {} 的心跳包信息：{}", ep_id, body);
                    break;
                case STATE:
                    // TODO 设备状态
                    log.info("收到来自设备 ep_id: {} 的数据信息：{}", ep_id, body);
                    break;
                default:
                    log.info(type.content + "消息内容: " + body);
                    break;
            }
        }

//        Message message = new Message(body, MessageEnum.CONNECT);
//        log.info("向客户端【{}】发送消息：{}", ctx.channel().id().asLongText(), message.toJsonString());
//        ctx.writeAndFlush(message);
    }

    /**
     * 设备下线处理
     *
     * @param ctx
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        String key = ctx.channel().id().asLongText();
        ChannelMap.removeChannelByName(key);
        log.info("设备下线了: {}", key);
    }

    /**
     * 设备连接异常处理
     *
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 打印异常
        log.info("异常：{}", cause.getMessage());
        String key = ctx.channel().id().asLongText();
        ChannelMap.removeChannelByName(key);
        //cause.printStackTrace();
        // 关闭连接
        ctx.close();
    }
}
